package com.trip.wechat.platform.subsystem.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.trip.wechat.platform.model.AccessTokenBO;
import com.trip.wechat.platform.subsystem.AccessTokenFacade;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 功能说明: 第三方平台 - AccessToken实现<br>
 * 系统说明: <br>
 * 模块说明: <br>
 * 功能描述: <br>
 */
@Component("wx.accessToken")
public class AccessTokenFacadeWXImpl implements AccessTokenFacade {

    final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Value("${wx.access_token.url:http://172.16.46.154:8080/RoxBusiness/wxauth/getToken.do}")
    protected String accessTokenUrl;

    @Autowired
    OkHttpClient httpClient;

    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public AccessTokenBO fetchAccessToken(String appId, String appSecret, String publicKey) {

        if (Strings.isNullOrEmpty(publicKey)) {
            LOGGER.warn("[wx.accessToken.fetchAccessToken] publicKey cannot be empty!");
//            return createResult(CodeDict.C_SERVICE_FAIL, "publicKey is empty");
        }
        AccessTokenRequestBody body = new AccessTokenRequestBody();
        body.setPublicKey(publicKey);
        try {
            LOGGER.info("[wx.accessToken.fetchAccessToken] request => {}", accessTokenUrl);
            Request request = new Request.Builder()
                    .url(accessTokenUrl)
                    .post(RequestBody.create(MediaType.parse("application/json"), objectMapper.writeValueAsBytes(body)))
                    .build();
            Response response = httpClient.newCall(request).execute();

            String responseBody = response.body().string();
            LOGGER.info("[wx.accessToken.fetchAccessToken] response => {}", responseBody);
            AccessTokenResponseBody resp = objectMapper.readValue(responseBody, AccessTokenResponseBody.class);
            AccessTokenBO bo = new AccessTokenBO();
            if ( resp.getCode() != null ) {
                bo.setErrcode(resp.getCode());
                bo.setAccessToken(resp.getToken());
            } else {
//                bo.setErrcode(CodeDict.C_SERVICE_FAIL);
                bo.setErrmsg(resp.getMsg());
            }
            return bo;
        } catch (IOException e) {
            LOGGER.warn("[wx.accessToken.fetchAccessToken] failed! IOException! {}", e.getMessage());
//            return createResult(CodeDict.C_SERVICE_FAIL, "fetch token failed! IOException!");
        } catch (Exception e) {
            LOGGER.warn("[wx.accessToken.fetchAccessToken] failed! {}! {}", e.getClass().getName(), e.getMessage());
//            return createResult(CodeDict.C_SERVICE_FAIL, "fetch token failed!");
        }
        return null;
    }

    public static class AccessTokenRequestBody {
        private String publicKey;

        public String getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(String publicKey) {
            this.publicKey = publicKey;
        }
    }

    public static class AccessTokenResponseBody {
        private Integer code;
        private String token;
        private String msg;

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }
    }

    protected AccessTokenBO createResult(int code, String message) {
        AccessTokenBO resultBO = new AccessTokenBO();
        resultBO.setErrcode(code);
        resultBO.setErrmsg(message);
        return resultBO;
    }
}
